﻿using System.IO;
using UnityEditor;
using UnityEngine.SceneManagement;
using UnityEngine;
using UnityEngine.AI;
using System.Collections.Generic;
using System;
using System.Text;


//navmesh导出数据
public class NavMeshExport : MonoBehaviour
{
    static string GetExportPath
    {
        get
        {
            string path = Application.dataPath + "/RecastNav/obj/" + SceneManager.GetActiveScene().name + ".obj";
            string dir = Path.GetDirectoryName(path);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            return path;
        }
    }

    [MenuItem("NavMesh/Export")]
    static void Export()
    {
        Debug.Log("NavMesh Export Start");

        NavMeshTriangulation navMeshTriangulation = NavMesh.CalculateTriangulation();

        //新建文件
        StreamWriter streamWriter = new StreamWriter(GetExportPath);

        //顶点  
        for (int i = 0; i < navMeshTriangulation.vertices.Length; i++)
        {
            streamWriter.WriteLine("v  " + navMeshTriangulation.vertices[i].x + " " + navMeshTriangulation.vertices[i].y + " " + navMeshTriangulation.vertices[i].z);
        }

        streamWriter.WriteLine("g pPlane1");

        //索引  
        for (int i = 0; i < navMeshTriangulation.indices.Length;)
        {
            streamWriter.WriteLine("f " + (navMeshTriangulation.indices[i] + 1) + " " + (navMeshTriangulation.indices[i + 1] + 1) + " " + (navMeshTriangulation.indices[i + 2] + 1));
            i = i + 3;
        }

        streamWriter.Flush();
        streamWriter.Close();


        AssetDatabase.Refresh();

        Debug.Log("NavMesh Export Success");
    }

    static int vertexOffset = 0;
    static int normalOffset = 0;
    static int uvOffset = 0;
    static int meshIndex = 0;

    static void Clear() {
        vertexOffset = 0;
        normalOffset = 0;
        uvOffset = 0;
        meshIndex = 0;
    }

    [MenuItem("NavMesh/ExportByCollider")]
    static void ExportByCollider()
    {
        Debug.Log("NavMesh Export Start");

        //新建文件
        StreamWriter streamWriter = new StreamWriter(GetExportPath);

        Dictionary<Vector3, int> cache = new Dictionary<Vector3, int>();
        Dictionary<int, int> cache2 = new Dictionary<int, int>();


        Collider[] meshFilters = FindObjectsOfType<BoxCollider>();
        foreach (Collider mf in meshFilters)
        {
            BoxCollider boxCollider = mf as BoxCollider;
            if (boxCollider.gameObject.activeInHierarchy)
            {
                GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
                cube.transform.SetParent(mf.transform);
                cube.transform.localScale = boxCollider.size;
                cube.transform.localRotation = Quaternion.identity;
                cube.transform.localPosition = boxCollider.center;

                Mesh mesh = cube.GetComponent<MeshFilter>().sharedMesh;

                streamWriter.WriteLine(ColliderToMethString(cube.transform, mesh));

                DestroyImmediate(cube);
            }
        }

        meshFilters = FindObjectsOfType<MeshCollider>();
        foreach (Collider mf in meshFilters)
        {
            if (mf.gameObject.activeInHierarchy)
            {
                Mesh mesh = (mf as MeshCollider).sharedMesh;

                streamWriter.WriteLine(ColliderToMethString(mf.transform, mesh));
            }
        }

        streamWriter.Flush();
        streamWriter.Close();


        AssetDatabase.Refresh();

        Debug.Log("NavMesh Export Success");
    }

    static string ColliderToMethString(Transform transform, Mesh mesh)
    {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.Append("mtllib ./" + SceneManager.GetActiveScene().name + ".mtl\n");

        stringBuilder.Append($"g Mesh_{++meshIndex}\n");
        foreach (Vector3 lv in mesh.vertices)
        {
            Vector3 wv = transform.TransformPoint(lv);
            stringBuilder.Append(string.Format("v {0} {1} {2}\n", -wv.x, wv.y, wv.z));
        }
        stringBuilder.Append("\n");

        foreach (Vector3 lv in mesh.normals)
        {
            Vector3 wv = transform.TransformDirection(lv);
            stringBuilder.Append(string.Format("vn {0} {1} {2}\n", -wv.x, wv.y, wv.z));
        }
        stringBuilder.Append("\n");

        foreach (Vector3 v in mesh.uv)
        {
            stringBuilder.Append(string.Format("vt {0} {1}\n", v.x, v.y));
        }
        stringBuilder.Append("\n");

        stringBuilder.Append("usemtl Default-Material\n");
        stringBuilder.Append("usemap Default-Material\n");
        for (int i = 0; i < mesh.triangles.Length; i += 3)
        {
            stringBuilder.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n",
                mesh.triangles[i] + 1 + vertexOffset,
                mesh.triangles[i + 1] + 1 + normalOffset,
                mesh.triangles[i + 2] + 1 + uvOffset));
        }

        vertexOffset += mesh.vertices.Length;
        normalOffset += mesh.normals.Length;
        uvOffset += mesh.uv.Length;

        return stringBuilder.ToString();
    }
}